package com.sky.spring.factory;

import com.sky.spring.pojo.Account;
import com.sky.spring.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Description:
 * 动态代理工厂类
 *
 * @author Sky
 * @Date 2021/7/31 14:33
 */
@Component("proxyFactory")
public class ProxyFactory {

    @Autowired
   private TransactionManager transactionManager;

    /**
     * 使用JDK动态代理获得代理对象
     *
     * @param object 委托对象
     * @return 代理对象
     */
    public Object getJdkProxy(Object object) {
        return Proxy.newProxyInstance(
                object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), new InvocationHandler() {

                    /**
                     * @param proxy 代理对象本身
                     * @param method 调用的方法，动态 指定
                     * @param args 方法参数
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object proxyObj = null;
                        try {
                            //手动开启事务
                            transactionManager.beginTransaction();

                            proxyObj = method.invoke(object, args);

                            // 提交事务
                            transactionManager.commit();

                        } catch (Exception e) {

                            e.printStackTrace();

                            // 回滚事务
                            transactionManager.rollBack();

                            throw e;
                        }

                        return proxyObj;
                    }
                });
    }

    /**
     * 使用cglib动态代理获得代理对象
     *
     * @param obj 委托对象
     * @return 代理对象
     */
    public Object getCglibProxy(Object obj) {
        return Enhancer.create(obj.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object proxyObj = null;
                try {
                    //手动开启事务
                    transactionManager.beginTransaction();

                    proxyObj = method.invoke(object, args);

                    // 提交事务
                    transactionManager.commit();

                } catch (Exception e) {

                    e.printStackTrace();

                    // 回滚事务
                    transactionManager.rollBack();

                    throw e;
                }

                return proxyObj;
            }
        });
    }
}
